package com.hcy.app.utils

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import android.graphics.Point
import android.hardware.camera2.CameraCharacteristics
import android.hardware.camera2.CameraManager
import android.location.LocationManager
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.wifi.WifiManager
import android.os.Build
import android.os.Environment
import android.os.StatFs
import android.provider.Settings
import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import android.text.format.Formatter
import android.view.WindowManager
import androidx.annotation.RequiresPermission
import java.io.File
import java.net.NetworkInterface
import java.util.Collections
import java.util.Scanner
// object 和 class，object 相当于 spring 中的单例class，适合于全局单例对象声明，线程安全。一般会用在工具类上。
// spring 中的单例模式是使用频率最高的，估计kt是吸取的spring的经验直接使用了一个关键字来处理这种高频场景
object DeviceInfo {

    // 获取Android 版本，eg：15
    fun getAndroidVersion():String{
        return Build.VERSION.RELEASE
    }
    // 型号、eg：PJZ110
    fun getModel():String{
        return Build.MODEL
    }
    // 品牌、eg：OnePlus
    fun getBrand(): String{
        return Build.BRAND
    }
    // 获取 cpu 信息，eg：
    fun getCpuInfo():String{
        return try {
            val cpuInfo = File("/proc/cpuinfo").readText()
            val modelLine = cpuInfo.lines().find { it.contains("model name") || it.contains("Hardware") }
            modelLine?.substringAfter(":")?.trim() ?: "Unknown CPU"
        } catch (e: Exception) {
            "Failed to read CPU info: ${e.message}"
        }
    }

    /**
     * 获取设备标识符 (优先尝试获取IMEI，失败时使用Android ID)
     */
    @SuppressLint("HardwareIds")
    fun getIMEI(ctx: Context): String{
        return try {
            // Android 10+ 无法获取IMEI
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                return getAndroidId(ctx)
            }

            val telephonyManager = ctx.getSystemService(
                Context.TELEPHONY_SERVICE
            ) as TelephonyManager

            // 尝试获取IMEI
            val imei = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                telephonyManager.imei ?: getAndroidId(ctx)
            } else {
                @Suppress("DEPRECATION")
                telephonyManager.deviceId ?: getAndroidId(ctx)
            }
            imei
        } catch (e: SecurityException) {
            // 权限缺失时回退到Android ID
            getAndroidId(ctx)
        }
    }

    @SuppressLint("HardwareIds")
    private fun getAndroidId(ctx:Context):String{
        val androidId = Settings.Secure.getString(ctx.contentResolver, Settings.Secure.ANDROID_ID)
        return androidId
    }

    @RequiresPermission(allOf = [Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION])
    fun getGPSInfo(context: Context): String {
        var str = ""
        val locationManager: LocationManager =
            context.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        // 获取最后已知位置
        val lastLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
        lastLocation?.let {
            str= "[${it.latitude}, ${it.longitude}] 精度: ${it.accuracy} 米"
        }
        return str
    }

    // 获取 ip 信息
    fun getIPAddress(context: Context): String {
        try {
            val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
            if (wifiManager.isWifiEnabled) {
                return Formatter.formatIpAddress(wifiManager.connectionInfo.ipAddress)
            }

            val interfaces = Collections.list(NetworkInterface.getNetworkInterfaces())
            for (intf in interfaces) {
                val addrs = Collections.list(intf.inetAddresses)
                for (addr in addrs) {
                    if (!addr.isLoopbackAddress) {
                        val sAddr = addr.hostAddress
                        if ((sAddr?.indexOf(':') ?: -1) < 0) {
                            return sAddr ?: "0.0.0.0"
                        }
                    }
                }
            }
        } catch (ex: Exception) {
            ex.printStackTrace()
        }
        return "0.0.0.0"
    }
    // 获取内存信息
    fun getMemoryInfo(): String {
        return try {
            val reader = Runtime.getRuntime().exec("cat /proc/meminfo").inputStream.bufferedReader()
            var totalMemory: Long = 0

            reader.useLines { lines ->
                lines.forEach { line ->
                    if (line.startsWith("MemTotal")) {
                        val parts = line.split("\\s+".toRegex()) // 使用正则表达式处理空格
                        if (parts.size >= 2) {
                            totalMemory = parts[1].toLong() // 获取以 KB 为单位的内存值
                        }
                        return@forEach
                    }
                }
            }

            // 转换为 MB
            if (totalMemory > 0) {
                "总内存大小: ${totalMemory / 1024} MB"
            } else {
                "未知"
            }
        } catch (e: Exception) {
            "未知"
        }
    }
    // 获取存储信息
    fun getStorageInfo(): String {
        val stat = StatFs(Environment.getDataDirectory().path)
        val blockSize = stat.blockSizeLong
        val totalBlocks = stat.blockCountLong
        val availableBlocks = stat.availableBlocksLong

        // 转换为GB
        val totalStorage = blockSize * totalBlocks / (1024 * 1024 * 1024) // 以GB为单位
        val availableStorage = blockSize * availableBlocks / (1024 * 1024 * 1024) // 以GB为单位

        return "总存储大小: $totalStorage GB, 可用存储: $availableStorage GB"
    }
    // 获取软件信息
    fun getInstalledApps(context: Context): List<AppInfo> {
        val pm = context.packageManager
        val appList = mutableListOf<AppInfo>()

        // 核心 API：获取安装包列表
        val packages = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            pm.getInstalledPackages(PackageManager.PackageInfoFlags.of(0))
        } else {
            @Suppress("DEPRECATION")
            pm.getInstalledPackages(0)
        }

        packages.forEach { pkgInfo ->
            appList.add(
                AppInfo(
                    name = pkgInfo.applicationInfo?.loadLabel(pm).toString(),
                    packageName = pkgInfo.packageName,
                    versionName = pkgInfo.versionName ?: "N/A",
                    versionCode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                        pkgInfo.longVersionCode
                    } else {
                        @Suppress("DEPRECATION")
                        pkgInfo.versionCode.toLong()
                    },
//                    icon = pkgInfo.applicationInfo?.loadIcon(pm) ?: null,
                    isSystemApp = (pkgInfo.applicationInfo?.flags?.and(ApplicationInfo.FLAG_SYSTEM)) != 0
                )
            )
        }
        return appList
    }


    // 检查设备是否越狱
    fun isDeviceRooted(): Boolean {
        // 检查常见的root二进制文件
        val knownRootPaths = arrayOf(
            "/system/bin/su",
            "/system/xbin/su",
            "/sbin/su",
            "/data/local/bin/su",
            "/data/local/xbin/su",
            "/data/local/su",
            "/system/bin/failsafe/su",
            "/system/sd/xbin/su",
            "/system/usr/we-need-root/su",
            "/su/bin/su"
        )

        // 检查是否存在su文件
        if (knownRootPaths.any { File(it).exists() }) {
            return true
        }

        // 检查build tags是否包含test-keys
        val buildTags = Build.TAGS
        if (buildTags != null && buildTags.contains("test-keys")) {
            return true
        }

        // 尝试执行su命令
        return try {
            Runtime.getRuntime().exec("su")
            true
        } catch (e: Exception) {
            false
        }
    }
    // 检查设备是否开启 usb 调试
    fun isUsbDebuggingEnabled(ctx: Context): Boolean {
        return try {
            val contentResolver = ctx.contentResolver
            val adbEnabled = Settings.Global.getInt(contentResolver, Settings.Global.ADB_ENABLED, 0)
            adbEnabled == 1
        } catch (e: Exception) {
            false
        }
    }

    // 检查设备是否开启了 vpn 代理
    fun isVpnActive(ctx: Context): Boolean {
        val connectivityManager = ctx.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val activeNetwork = connectivityManager.activeNetwork
            val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
            capabilities?.hasTransport(NetworkCapabilities.TRANSPORT_VPN) ?: false
        } else {
            @Suppress("DEPRECATION")
            connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_VPN)?.isConnectedOrConnecting ?: false
        }
    }
    // 屏幕信息
    fun getScreenInfo(ctx: Context): String {
        val windowManager = ctx.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        val width: Int
        val height: Int
        val refreshRate = windowManager.defaultDisplay.refreshRate
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val windowMetrics = windowManager.currentWindowMetrics
            val bounds = windowMetrics.bounds
            width = bounds.width()
            height = bounds.height()
            "宽度: ${bounds.width()}px\n高度: ${bounds.height()}px"
        } else {
            val size = Point()
            width = size.x
            height = size.y
            "宽度: ${size.x}px\n高度: ${size.y}px"
        }
        return "$width x $height, $refreshRate HZ"
    }


    @Deprecated("我的手机测试还未通过")
    @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
    fun getSimInfo(ctx : Context): String{
        val telephonyManager = ctx.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        val stringBuilder = StringBuilder()

        // 单卡信息（兼容旧设备）
        // 双卡设备处理
        val subscriptionManager = ctx.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
        val subscriptionInfoList = subscriptionManager.activeSubscriptionInfoList

        if (subscriptionInfoList.isNullOrEmpty()) {
            stringBuilder.append("No active SIM cards")
        } else {
            for ((index, info) in subscriptionInfoList.withIndex()) {
                stringBuilder.append("【SIM ${index + 1}】\n")
                stringBuilder.append(getSimCardInfo(telephonyManager, info))
                stringBuilder.append("\n")
            }
        }
        return stringBuilder.toString()
    }

    fun getSimCardInfo(
        telephonyManager: TelephonyManager,
        subscriptionInfo: SubscriptionInfo? = null
    ): String {
        return buildString {
            // SIM状态
            append("State: ")
            append(
                when (telephonyManager.simState) {
                    TelephonyManager.SIM_STATE_ABSENT -> "ABSENT"
                    TelephonyManager.SIM_STATE_READY -> "READY"
                    TelephonyManager.SIM_STATE_PIN_REQUIRED -> "PIN_REQUIRED"
                    TelephonyManager.SIM_STATE_PUK_REQUIRED -> "PUK_REQUIRED"
                    TelephonyManager.SIM_STATE_NETWORK_LOCKED -> "NETWORK_LOCKED"
                    else -> "UNKNOWN"
                }
            )
            append("\n")

            // ICCID (SIM卡序列号)
            append("ICCID: ")
            append(subscriptionInfo?.iccId ?: telephonyManager.simSerialNumber ?: "Unavailable")
            append("\n")

            // 运营商信息
            append("Operator: ")
            append(subscriptionInfo?.carrierName ?: telephonyManager.simOperatorName)
            append("\n")

            // 国家代码
            append("Country: ")
            append(telephonyManager.simCountryIso.uppercase())
            append("\n")
        }
    }

    fun getCameraInfo(context: Context): String {
        val cameraManager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
        val cameraList = cameraManager.cameraIdList
        val cameraInfo = StringBuilder("Cameras: \n")
        cameraList.forEach { cameraId ->
            val characteristics = cameraManager.getCameraCharacteristics(cameraId)
            val facing = characteristics.get(CameraCharacteristics.LENS_FACING)
            val lensFacing = if (facing == CameraCharacteristics.LENS_FACING_FRONT) "Front" else "Back"
            cameraInfo.append("Camera ID: $cameraId, Facing: $lensFacing\n")
        }
        return cameraInfo.toString()
    }

}

// 数据类封装应用信息
data class AppInfo(
    val name: String,
    val packageName: String,
    val versionName: String,
    val versionCode: Long,
//    val icon: Drawable?,
    val isSystemApp: Boolean
)